package com.example.demo.view;

import static androidx.core.math.MathUtils.clamp;

import android.content.Context;
import android.content.res.TypedArray;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;

import com.example.demo.R;
import com.example.demo.util.ToastUtil;

public class InputCounterView extends LinearLayout {
    private Button decreaseButton;   // 减少按钮
    private Button increaseButton;   // 增加按钮
    private EditText valueEditText;  // 数值编辑框

    private int minValue     = 0;    // 最小值
    private int maxValue     = 100;  // 最大值
    private int increment    = 1;    // 最大值
    private int defaultValue = 0;    // 默认值
    private TextWatcher textWatcher; // 文本监听器
    private OnValueChangedListener valueChangedListener; // 数值变化监听器

    public InputCounterView(Context context) {
        super(context);
        init(context);
    }

    public InputCounterView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
        applyAttributes(context, attrs);
    }

    public InputCounterView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
        applyAttributes(context, attrs);
    }

    private void init(Context context) {
        LayoutInflater inflater = LayoutInflater.from(context);
        inflater.inflate(R.layout.counter_view_layout, this);

        decreaseButton = findViewById(R.id.decrease_button);
        increaseButton = findViewById(R.id.increase_button);
        valueEditText = findViewById(R.id.value_edit_text);

        decreaseButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                decreaseValue();
            }
        });

        increaseButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                increaseValue();
            }
        });

        textWatcher = new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                if (valueChangedListener != null) {
                    int value;
                    try {
                        value = Integer.parseInt(charSequence.toString());
                        // 确保值在最小值和最大值之间
                        if (value < minValue) {
                            value = minValue;
                            ToastUtil.showShort("输入数字不能小于最小值 " + minValue);
                        } else if (value > maxValue) {
                            value = maxValue;
                            ToastUtil.showShort("输入数字不能大于最大值 " + maxValue);
                        }
                        // 更新输入框中的值
                        setEditTextValue(String.valueOf(value));
                        // 将光标移动到文本末尾
                        valueEditText.setSelection(valueEditText.getText().length());
                    } catch (NumberFormatException e) {
                        value = minValue;
                    }
                    valueChangedListener.onValueChanged(value);
                }
            }

            @Override
            public void afterTextChanged(Editable editable) {
            }
        };

        valueEditText.addTextChangedListener(textWatcher);

        setValue(defaultValue);
    }

    private void applyAttributes(Context context, AttributeSet attrs) {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CounterView);
        try {
            increment = a.getInt(R.styleable.CounterView_increment, increment);
            minValue = a.getInt(R.styleable.CounterView_minValue, minValue);
            maxValue = a.getInt(R.styleable.CounterView_maxValue, maxValue);
            defaultValue = a.getInt(R.styleable.CounterView_defaultValue, defaultValue);
        } finally {
            a.recycle();
        }
    }

    /**
     * 设置默认值
     * @param defaultValue 默认值
     */
    public void setDefaultValue(int defaultValue) {
        this.defaultValue = defaultValue;
        setValue(defaultValue);
    }

    /**
     * 设置最小值
     * @param minValue 最小值
     */
    public void setMinValue(int minValue) {
        this.minValue = minValue;
    }

    /**
     * 设置最大值
     * @param maxValue 最大值
     */
    public void setMaxValue(int maxValue) {
        this.maxValue = maxValue;
    }

    /**
     * 设置步进值。
     *
     * @param increment 步进值
     */
    public void setIncrement(int increment) {
        this.increment = increment;
    }

    /**
     * 获取当前数值。
     *
     * @return 当前数值
     */
    public int getValue() {
        try {
            int value = Integer.parseInt(valueEditText.getText().toString());
            return clamp(value, minValue, maxValue);
        } catch (NumberFormatException e) {
            return minValue;
        }
    }

    /**
     * 设置数值。
     *
     * @param value 数值
     */
    public void setValue(int value) {
        setEditTextValue(String.valueOf(clamp(value, minValue, maxValue)));
    }

    /**
     * 更新文本数据，并将光标移动到文本的最后一行！
     * 修改因为文本监听导致光标跑到最前端！
     * @param value
     */
    private void setEditTextValue(String value) {
        String currentText = valueEditText.getText().toString();
        if (!currentText.equals(value)) {
            valueEditText.setText(value);
            // 将光标移动到文本的末尾
            valueEditText.setSelection(valueEditText.getText().length());
        }
    }

    /**
     * 减少数值。如果当前数值大于最小值，则减少步进值并更新数值文本。
     */
    private void decreaseValue() {
        valueEditText.removeTextChangedListener(textWatcher);
        int currentValue = getValue();
        if (currentValue > minValue) {
            int newValue = currentValue - increment;
            if (newValue != currentValue) {
                setValue(newValue);
                notifyValueChanged();
            }
        } else {
            ToastUtil.showShort("输入数字不能小于最小值 " + minValue);
        }
        valueEditText.addTextChangedListener(textWatcher);
    }

    /**
     * 增加数值。如果当前数值小于最大值，则增加步进值并更新数值文本。
     */
    private void increaseValue() {
        valueEditText.removeTextChangedListener(textWatcher);
        int currentValue = getValue();
        if (currentValue < maxValue) {
            int newValue = currentValue + increment;
            if (newValue != currentValue) {
                setValue(newValue);
                notifyValueChanged();
            }
        } else {
            ToastUtil.showShort("输入数字不能大于最大值 " + maxValue);
        }
        valueEditText.addTextChangedListener(textWatcher);
    }

    // 通知值已经改变
    private void notifyValueChanged() {
        if (valueChangedListener != null) {
            valueChangedListener.onValueChanged(getValue());
        }
    }

    public void setOnValueChangedListener(OnValueChangedListener listener) {
        this.valueChangedListener = listener;
    }

    public interface OnValueChangedListener {
        void onValueChanged(int newValue);
    }
}